import csv
import time
import sys
import os
from unittest import case

from util.graphdb_base import GraphDBBase

class DopamineDataVectors(GraphDBBase):
    def __init__(self, argv):
        super().__init__(command=__file__, argv=argv)

    def set_dopamine_gene_dosage_vectors(self):
        list_of_dopamine_participant_ids = """
            MATCH (n:DopamineASD)
            RETURN n.participantId as participantId
            UNION MATCH (n:DopamineDD)
            RETURN n.participantId as participantId
            """
        
        query = """
            MATCH (dgene:DopamineGene)
            WITH dgene
            ORDER BY id(dgene)
            MATCH (participant:Participant {participantId: $participantId})
            OPTIONAL MATCH (participant)-[d]->(dgene)
            WITH CASE WHEN d IS null THEN 0  
            WHEN d.geneDosage = -1 THEN (-1*1.0f)
            WHEN d.geneDosage = 2 THEN  (1*1.0f) END as value
            WITH collect(value) as vector
            MATCH (participant:Participant {participantId: $participantId})
            SET participant.dopamineGeneDosageVector = vector
        """

        with self._driver.session() as session:
            tx = session.begin_transaction()
            try:
                i = 0
                for participant in tx.run(list_of_dopamine_participant_ids):
                    participant_id = participant["participantId"]
                    tx.run(query, {"participantId": participant_id})

                    i += 1
                    if i % 100 == 0:
                        tx.commit
                        print(i, "dopamine gene dosage vectors created")


                tx.commit()
                print(i, "dopamine gene dosage vectors created")
            
            except Exception as e:
                print(e, participant_id)
                exit

    def set_dopamine_go_vectors(self):
        list_of_dopamine_participant_ids = """
            MATCH (n:DopamineASD)
            RETURN n.participantId as participantId
            UNION MATCH (n:DopamineDD)
            RETURN n.participantId as participantId
            """

        query ="""
            MATCH (participant:Participant {participantId: $participantId})-[]->(gene:DopamineGene)-[]->(go:DopamineGo)
            WITH count(go) as total
            MATCH (feature:DopamineGo)
            WITH  feature, total
            ORDER BY id(feature)
            MATCH (participant:Participant {participantId: $participantId})
            OPTIONAL MATCH (participant)-[:DELETED]->(:DopamineGene)-[del]->(feature)
            WITH participant, feature, total, count(del) as total_del
            OPTIONAL MATCH (participant)-[:DUPLICATED]->(:DopamineGene)-[dup]->(feature)
            WITH feature, total, total_del, count(dup) as total_dup
            WITH collect(((-1.0f*total_del) + (1.0f*total_dup))/(total*1.0f)) as vector
            MATCH (participant:Participant {participantId: $participantId})
            SET participant.dopamineGoVector = vector
            """

        with self._driver.session() as session:
            tx = session.begin_transaction()
            try:
                i = 0
                for participant in tx.run(list_of_dopamine_participant_ids):
                    participant_id = participant["participantId"]
                    tx.run(query, {"participantId": participant_id})

                    i += 1
                    if i % 100 == 0:
                        tx.commit
                        print(i, "dopamine GO vectors created")


                tx.commit()
                print(i, "dopamine GO vectors created")
            except Exception as e:
                print(e, participant_id)
                exit
        
if __name__ == '__main__':
    data_vectors = DopamineDataVectors(sys.argv[1:])
    start = time.time()
    data_vectors.set_dopamine_gene_dosage_vectors()
    data_vectors.set_dopamine_go_vectors()
    end = time.time() - start
    data_vectors.close()
    print("Time to complete:", end)